package cn.spream.dream.manager.user.impl;

import cn.spream.dream.dao.user.UserDao;
import cn.spream.dream.domain.CacheKeyEnum;
import cn.spream.dream.domain.user.User;
import cn.spream.dream.manager.BaseManager;
import cn.spream.dream.manager.user.UserManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import javax.annotation.Resource;

/**
 * 数据管理层
 * Created with IntelliJ IDEA.
 * User: sjx
 * Date: 13-6-5
 * Time: 下午11:31
 * To change this template use File | Settings | File Templates.
 */
@Repository("userManager")
public class UserManagerImpl extends BaseManager implements UserManager {

    private static final Log log = LogFactory.getLog(UserManagerImpl.class);

    @Resource(name = "userDao")
    private UserDao userDao;

    @Override
    public boolean add(final User user) {
        //编程式事务控制
        boolean added = (Boolean) transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                //异常后会自动回滚事务，或者使用下面代码手动控制事务
//                status.setRollbackOnly();
                return userDao.add(user);
            }
        });
        return added;
    }

    @Override
    public boolean deleteById(final long id) {
        //先删除缓存中的数据
        deleteUserWithCache(id);
        //不管缓存删除是否成功都删除数据库数据
        boolean deleted = (Boolean) transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                return userDao.deleteById(id);
            }
        });
        return deleted;
    }

    @Override
    public boolean updateById(final User user) {
        //先删除缓存中的数据
        deleteUserWithCache(user.getId());
        //不管缓存删除是否成功都更新数据库数据
        boolean updated = (Boolean) transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                return userDao.updateById(user);
            }
        });
        return updated;
    }

    @Override
    public User getUserWithCache(long id) {
        User user = null;
        CacheKeyEnum keyEnum = CacheKeyEnum.USER;
        String key = keyEnum.format(id);
        try {
            //从缓存中获取用户信息
            user = (User) cacheHelper.get(key);
        } catch (Exception e) {
            log.error("从缓存中获取用户信息时出错了,id=" + id, e);
        }
        try {
            if (user == null) {
                //缓存中没有则去数据库中取
                user = userDao.getById(id);
                if (user != null) {
                    //数据库中存在则添加到缓存中
                    cacheHelper.add(key, keyEnum.getExp(), user);
                }
            }
        } catch (Exception e) {
            log.error("从数据库中获取用户信息时出错了,id=" + id, e);
        }
        return user;
    }

    @Override
    public boolean deleteUserWithCache(long id) {
        boolean deleted = false;
        try {
            deleted = cacheHelper.delete(CacheKeyEnum.USER.format(id));
            //删除失败则记录日志
            if (deleted == false) {
                log.error("删除缓存中的用户信息时失败了,id=" + id);
            }
        } catch (Exception e) {
            log.error("删除缓存中的用户信息时出错了,id=" + id, e);
        }
        return deleted;
    }

}
